#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

#include "MDD.h"
#include "MDX.h"

// 命名空间别名
namespace fs = std::filesystem;

// 显示帮助信息
void show_help(const std::string& program_name) {
    std::cout << "用法: " << program_name << " [选项] <mdx或mdd文件>"
              << std::endl;
    std::cout << "选项:\n";
    cout << "  -i, --inter    交互式查询\n";
    std::cout << "  -h, --help           显示帮助信息\n";
    std::cout << "  -o, --output <目录>  指定输出目录（默认为当前目录）\n";
    std::cout << "  -s, --substyle       对MDX文件启用样式替换\n";
    std::cout << "  -p, --password <密码> 指定加密文件的密码\n";
    std::cout << "  --list-only          仅列出文件内容，不提取\n";
}

// 提取MDX文件内容
void extract_mdx(const std::string& filename, const std::string& output_dir,
                 bool substyle, const std::string& password) {
    try {
        // 准备密码
        std::pair<std::vector<uint8_t>, std::string> passcode;
        if (!password.empty()) {
            passcode.first =
                std::vector<uint8_t>(password.begin(), password.end());
            passcode.second = password;
        }

        // 创建MDX对象
        MDX mdx(filename, "", substyle, passcode);

        std::cout << "词典条目数量: " << mdx.size() << std::endl;
        // mdx.items();
        auto ret = mdx.query("output");
        cout << (ret) << endl;

        string word;
        string prompt("(mdx)>>>");
        cout << prompt;
        while (std::cin >> word) {
            if (word == "quit") break;
            cout << mdx.query(word) << endl;
            // cout << word << endl;
            cout << prompt;
        }
        cout << "!!![finish]!!!" << endl;
        return;

        // 创建输出目录
        fs::create_directories(output_dir);

        // 提取所有条目到文本文件
        std::string output_file =
            output_dir + "/" + fs::path(filename).stem().string() + ".txt";
        std::ofstream outfile(output_file, std::ios::binary);

        int count = 0;
        const int batch_size = 100;  // 每处理100个条目显示进度

        for (const auto& item : mdx.items()) {
            const std::string& key = item.first;
            const std::vector<uint8_t>& value = item.second;

            outfile.write(key.data(), key.size());
            outfile.write("\r\n", 2);
            outfile.write(reinterpret_cast<const char*>(value.data()),
                          value.size());
            outfile.write("\r\n</>\r\n", 7);

            count++;
            if (count % batch_size == 0) {
                // std::cout << "已处理: " << count << " 个条目" << std::endl;
            }
        }

        outfile.close();
        std::cout << "提取完成！文件保存到: " << output_file << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << std::endl;
    }
}

// 提取MDD文件内容
void extract_mdd(const std::string& filename, const std::string& output_dir,
                 const std::string& password) {
    try {
        // 准备密码
        std::pair<std::vector<uint8_t>, std::string> passcode;
        if (!password.empty()) {
            passcode.first =
                std::vector<uint8_t>(password.begin(), password.end());
            passcode.second = password;
        }

        // 创建MDD对象
        MDD mdd(filename, passcode);

        std::cout << "资源文件数量: " << mdd.size() << std::endl;

        // 创建输出目录
        fs::create_directories(output_dir);

        int count = 0;
        const int batch_size = 100;  // 每处理100个条目显示进度

        // 提取所有资源文件
        for (const auto& item : mdd.items()) {
            const std::string& filename = item.first;
            const std::vector<uint8_t>& content = item.second;

            // 构建输出路径
            std::string output_path = output_dir + "/" + filename;

            // 确保目录存在
            fs::create_directories(fs::path(output_path).parent_path());

            // 写入文件
            std::ofstream outfile(output_path, std::ios::binary);
            outfile.write(reinterpret_cast<const char*>(content.data()),
                          content.size());
            outfile.close();

            count++;
            if (count % batch_size == 0) {
                std::cout << "已处理: " << count << " 个文件" << std::endl;
            }
        }

        std::cout << "提取完成！所有文件已保存到: " << output_dir << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << std::endl;
    }
}

// 仅列出文件内容，不提取
void list_content(const std::string& filename, const std::string& password) {
    try {
        // 准备密码
        std::pair<std::vector<uint8_t>, std::string> passcode;
        if (!password.empty()) {
            passcode.first =
                std::vector<uint8_t>(password.begin(), password.end());
            passcode.second = password;
        }

        // 判断文件类型
        std::string extension = fs::path(filename).extension().string();
        std::transform(extension.begin(), extension.end(), extension.begin(),
                       ::tolower);

        if (extension == ".mdx") {
            MDX mdx(filename, "", false, passcode);
            std::cout << "词典文件: " << filename << std::endl;
            std::cout << "条目数量: " << mdx.size() << std::endl;

            // 列出前10个条目
            std::cout << "\n前10个条目:\n";
            std::vector<std::string> keys = mdx.keys();
            for (size_t i = 0;
                 i < std::min(static_cast<size_t>(10), keys.size()); ++i) {
                std::cout << i + 1 << ". " << keys[i] << std::endl;
            }
        } else if (extension == ".mdd") {
            MDD mdd(filename, passcode);
            std::cout << "资源文件: " << filename << std::endl;
            std::cout << "文件数量: " << mdd.size() << std::endl;

            // 列出前10个文件名
            std::cout << "\n前10个文件名:\n";
            std::vector<std::string> keys = mdd.keys();
            for (size_t i = 0;
                 i < std::min(static_cast<size_t>(10), keys.size()); ++i) {
                std::cout << i + 1 << ". " << keys[i] << std::endl;
            }
        } else {
            std::cout << "不支持的文件类型: " << extension << std::endl;
        }
    } catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << std::endl;
    }
}

int main(int argc, char* argv[]) {
    // 命令行参数默认值
    std::string output_dir = ".";
    bool substyle = false;
    std::string password = "";
    bool list_only = false;
    std::string filename = "";
    bool inter = false;

    // 解析命令行参数
    for (int i = 1; i < argc; ++i) {
        std::string arg = argv[i];

        if (arg == "-h" || arg == "--help") {
            show_help(argv[0]);
            return 0;
        } else if (arg == "-o" || arg == "--output") {
            if (i + 1 < argc) {
                output_dir = argv[++i];
            } else {
                std::cerr << "错误: -o 选项需要指定输出目录" << std::endl;
                show_help(argv[0]);
                return 1;
            }
        } else if (arg == "-s" || arg == "--substyle") {
            substyle = true;
        } else if (arg == "-p" || arg == "--password") {
            if (i + 1 < argc) {
                password = argv[++i];
            } else {
                std::cerr << "错误: -p 选项需要指定密码" << std::endl;
                show_help(argv[0]);
                return 1;
            }
        } else if (arg == "--list-only") {
            list_only = true;
        } else if (filename.empty()) {
            filename = arg;
        } else if (arg == "-i" || arg == "--inter") {
            inter = true;
        } else {
            std::cerr << "错误: 未知参数: " << arg << std::endl;
            show_help(argv[0]);
            return 1;
        }
    }

    // 检查是否提供了文件名
    if (filename.empty()) {
        std::cerr << "错误: 必须提供mdx或mdd文件" << std::endl;
        show_help(argv[0]);
        return 1;
    }

    // 检查文件是否存在
    if (!fs::exists(filename)) {
        std::cerr << "错误: 文件不存在: " << filename << std::endl;
        return 1;
    }

    // 判断文件类型并执行相应操作
    std::string extension = fs::path(filename).extension().string();
    std::transform(extension.begin(), extension.end(), extension.begin(),
                   ::tolower);

    if (list_only) {
        // 仅列出内容
        list_content(filename, password);
    } else {
        // 提取内容
        if (extension == ".mdx") {
            extract_mdx(filename, output_dir, substyle, password);
        } else if (extension == ".mdd") {
            extract_mdd(filename, output_dir, password);
        } else {
            std::cout << "不支持的文件类型，请提供.mdx或.mdd文件" << std::endl;
            show_help(argv[0]);
            return 1;
        }
    }

    // if (inter) {
    //     string word;
    //     string prompt("(mdx)>>>");
    //     cout << prompt;
    //     while (std::cin >> word) {
    //         cout << prompt;
    //     }
    // }

    return 0;
}
